package com.ruoyi.duty.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.duty.domain.DutyShift;
import com.ruoyi.duty.mapper.DutyShiftMapper;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.task.PatrolJob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.duty.mapper.DutyScheduleMapper;
import com.ruoyi.duty.domain.DutySchedule;
import com.ruoyi.duty.service.IDutyScheduleService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 排班计划Service业务层处理
 * 
 * @author yepanpan
 * @date 2025-05-08
 */
@Service
public class DutyScheduleServiceImpl implements IDutyScheduleService 
{
    private static final Logger log = LoggerFactory.getLogger(DutyScheduleServiceImpl.class);

    @Autowired
    private DutyScheduleMapper dutyScheduleMapper;
    @Autowired
    private DutyShiftMapper dutyShiftMapper;
    @Autowired
    private ISysDeptService deptService;
    @Autowired
    private ISysUserService userService;

    /**
     * 查询排班计划
     * 
     * @param id 排班计划主键
     * @return 排班计划
     */
    @Override
    public DutySchedule selectDutyScheduleById(Long id)
    {
        return dutyScheduleMapper.selectDutyScheduleById(id);
    }

    /**
     * 查询排班计划列表
     * 
     * @param dutySchedule 排班计划
     * @return 排班计划
     */
    @Override
    @DataScope(deptAlias = "t", userAlias = "t")
    public List<DutySchedule> selectDutyScheduleList(DutySchedule dutySchedule)
    {
        return dutyScheduleMapper.selectDutyScheduleList(dutySchedule);
    }

    /**
     * 新增排班计划
     * 
     * @param dutySchedule 排班计划
     * @return 结果
     */
    @Override
    @Transactional
    public int insertDutySchedule(DutySchedule dutySchedule)
    {
        DutyShift dutyShift = dutyShiftMapper.selectDutyShiftById(dutySchedule.getShiftId());
        if(dutyShift == null){
            throw new ServiceException("班次不存在");
        }
        SysUser sysUser = userService.selectUserById(dutySchedule.getUserId());
        dutySchedule.setUserName(sysUser.getNickName());
        if(StringUtils.isEmpty(dutySchedule.getStatus())){
            dutySchedule.setStatus(DutySchedule.STATUS_WAIT);
        }
        dutySchedule.setCreateTime(DateUtils.getNowDate());

        Date beginDay = dutySchedule.getBeginTime();
        Date endDay = dutySchedule.getEndTime();
        DutySchedule sc = new DutySchedule();
        int ret = 0;
        while (true){
            dutySchedule.setDutyDay(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, beginDay));
            dutySchedule.setBeginTime(DateUtils.parseDate(dutySchedule.getDutyDay()+" " + dutyShift.getStartTime()+":00"));
            dutySchedule.setEndTime(DateUtils.parseDate(dutySchedule.getDutyDay() + " " + dutyShift.getEndTime() + ":00"));
            if(dutyShift.getCrossDay().equalsIgnoreCase("Y")) {
                dutySchedule.setEndTime(DateUtils.addDays(dutySchedule.getEndTime(), 1));
            }

            // 验证是否存在旧数据
            sc.setDeptId(dutySchedule.getDeptId());
            sc.setDutyDay(dutySchedule.getDutyDay());
            sc.setUserId(dutySchedule.getUserId());
            sc.setShiftId(dutySchedule.getShiftId());
            List<DutySchedule> old = dutyScheduleMapper.selectDutyScheduleList(sc);
            if (StringUtils.isEmpty(old))
            {
                dutySchedule.setId(null);
                ret += dutyScheduleMapper.insertDutySchedule(dutySchedule);
            }

            if(dutySchedule.getDutyDay().equalsIgnoreCase(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, endDay))){
                break;
            }else{
                beginDay = DateUtils.addDays(beginDay, 1);
            }
        }

        return ret;
    }

    /**
     * 修改排班计划
     * 
     * @param dutySchedule 排班计划
     * @return 结果
     */
    @Override
    public int updateDutySchedule(DutySchedule dutySchedule)
    {
        dutySchedule.setUpdateTime(DateUtils.getNowDate());
        return dutyScheduleMapper.updateDutySchedule(dutySchedule);
    }

    /**
     * 批量删除排班计划
     * 
     * @param ids 需要删除的排班计划主键
     * @return 结果
     */
    @Override
    public int deleteDutyScheduleByIds(Long[] ids)
    {
        return dutyScheduleMapper.deleteDutyScheduleByIds(ids);
    }

    /**
     * 删除排班计划信息
     * 
     * @param id 排班计划主键
     * @return 结果
     */
    @Override
    public int deleteDutyScheduleById(Long id)
    {
        return dutyScheduleMapper.deleteDutyScheduleById(id);
    }


    /**
     * 导入数据
     *
     * @param dataList 数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName 操作用户
     * @return 结果
     */
    @Override
    public String importData(List<DutySchedule> dataList, Boolean isUpdateSupport, String operName){
        if (StringUtils.isNull(dataList) || dataList.size() == 0)
        {
            throw new ServiceException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        SysDept dc = new SysDept();
        dc.setDelFlag("0");
        dc.setDeptType("community");;
        List<SysDept> deptList = deptService.selectDeptList(dc);
        if(deptList == null || deptList.isEmpty()){
            throw new ServiceException("请先添加区域信息");
        }

        Map<String, Long> deptMap = deptList.stream().collect(Collectors.toMap(SysDept::getDeptName, SysDept::getDeptId));
        Map<String, Long> userMap = new HashMap<>();
        Map<String, DutyShift> shiftMap = new HashMap<>();

        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        DutySchedule sc = new DutySchedule();
        for (DutySchedule row : dataList)
        {
            try
            {
                if(StringUtils.isEmpty(row.getDeptName())){
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、排班 " + row.getUserName() + " 的区域信息不能为空");
                    continue;
                }
                if(StringUtils.isEmpty(row.getUserName())){
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、用户 " + row.getUserName() + " 姓名不能为空");
                    continue;
                }
                if(StringUtils.isEmpty(row.getShiftName())){
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、排班 " + row.getUserName() + " 的班次不能为空");
                    continue;
                }
                Long deptId = deptMap.get(row.getDeptName().trim());
                if(deptId == null){
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、区域 " + row.getDeptName() + " 不存在");
                    continue;
                }
                row.setDeptId(deptId);

                Long userId = userMap.get(row.getDeptId()+"_"+row.getUserName());
                if(userId == null){
                    SysUser uc = new SysUser();
                    uc.setDeptId(row.getDeptId());
                    uc.setDelFlag("0");
                    List<SysUser> userList = userService.selectUserList(uc);
                    if(userList != null){
                        userList.forEach(u->{
                            userMap.put(row.getDeptId()+"_"+u.getUserName(), u.getUserId());
                        });
                    }
                }
                userId = userMap.get(row.getDeptId()+"_"+row.getUserName());
                if(userId == null){
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、用户 " + row.getUserName() + " 不存在");
                    continue;
                }
                row.setUserId(userId);

                if(shiftMap.get(row.getDeptId()+"_"+row.getShiftName()) == null){
                    DutyShift dsc = new DutyShift();
                    dsc.setDeptId(row.getDeptId());
                    List<DutyShift> shiftList = dutyShiftMapper.selectDutyShiftList(dsc);
                    if(shiftList != null){
                        shiftList.forEach(s->{
                            shiftMap.put(row.getDeptId()+"_"+s.getName(), s);
                        });
                    }
                }
                DutyShift dutyShift = shiftMap.get(row.getDeptId()+"_"+row.getShiftName());
                if(dutyShift == null){
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、班次 " + row.getShiftName() + " 不存在");
                    continue;
                }
                row.setShiftId(dutyShift.getId());
                row.setBeginTime(DateUtils.parseDate(row.getDutyDay()+" " + dutyShift.getStartTime()+":00"));
                row.setEndTime(DateUtils.parseDate(row.getDutyDay() + " " + dutyShift.getEndTime() + ":00"));
                if(dutyShift.getCrossDay().equalsIgnoreCase("Y")) {
                    row.setEndTime(DateUtils.addDays(row.getEndTime(), 1));
                }

                if(StringUtils.isEmpty(row.getStatus())){
                    row.setStatus(DutySchedule.STATUS_WAIT);
                }

                sc.setDeptId(deptId);
                sc.setDutyDay(row.getDutyDay());
                sc.setUserId(row.getUserId());
                sc.setShiftId(row.getShiftId());
                // 验证是否存在旧数据
                List<DutySchedule> old = dutyScheduleMapper.selectDutyScheduleList(sc);
                if (StringUtils.isEmpty(old))
                {
                    row.setCreateBy(operName);
                    insertDutySchedule(row);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、排班 " + row.getDutyDay() + "-" + row.getUserName() + " 导入成功");
                }
                else if (isUpdateSupport)
                {
                    row.setId(old.get(0).getId());
                    row.setUpdateBy(operName);
                    updateDutySchedule(row);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、排班 " + row.getDutyDay() + "-" + row.getUserName() + " 更新成功");
                }
                else
                {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、排班 " + row.getDutyDay() + "-" + row.getUserName() + " 已存在");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + "、排班 " + row.getDutyDay() + "-" + row.getUserName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
}
